package com.zzw.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;

import java.io.File;
import java.time.Duration;
import java.util.Arrays;

/**
 * Redis配置类
 */
@Configuration
public class RedisConfig {

    @Value("${redis.host}")
    private String host;

    @Value("${redis.port}")
    private int port;

    @Value("${redis.password}")
    private String password;

    @Value("${redis.database}")
    private int database;

    @Value("${redis.timeout}")
    private int timeout;

    @Value("${redis.pool.max-active}")
    private int maxActive;

    @Value("${redis.pool.max-wait}")
    private int maxWait;

    @Value("${redis.pool.max-idle}")
    private int maxIdle;

    @Value("${redis.pool.min-idle}")
    private int minIdle;

    // 持久化配置
    @Value("${redis.persistence.rdb.enabled:true}")
    private boolean rdbEnabled;

    @Value("${redis.persistence.aof.enabled:true}")
    private boolean aofEnabled;

    @Value("${redis.config.path:./redis-config}")
    private String configPath;

    @Autowired(required = false)
    private String redisConfigFilePath;

    /**
     * 配置Jedis连接池
     */
    @Bean
    public JedisPoolConfig jedisPoolConfig() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        // 最大连接数
        jedisPoolConfig.setMaxTotal(maxActive);
        // 最大空闲连接数
        jedisPoolConfig.setMaxIdle(maxIdle);
        // 最小空闲连接数
        jedisPoolConfig.setMinIdle(minIdle);
        // 当连接池耗尽时，等待可用连接的最大时间，单位毫秒
        jedisPoolConfig.setMaxWaitMillis(maxWait);
        // 对拿到的connection进行validateObject校验
        jedisPoolConfig.setTestOnBorrow(true);
        return jedisPoolConfig;
    }

    /**
     * 配置Redis连接工厂
     */
    @Bean
    public RedisConnectionFactory redisConnectionFactory(JedisPoolConfig jedisPoolConfig) {
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        // 设置Redis服务器地址
        redisStandaloneConfiguration.setHostName(host);
        // 设置Redis端口号
        redisStandaloneConfiguration.setPort(port);
        // 设置Redis密码
        if (password != null && !password.isEmpty()) {
            redisStandaloneConfiguration.setPassword(password);
        }
        // 设置数据库索引
        redisStandaloneConfiguration.setDatabase(database);

        // 获取默认的Jedis连接池配置
        JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpBuilder =
                (JedisClientConfiguration.JedisPoolingClientConfigurationBuilder) JedisClientConfiguration.builder();
        // 指定Jedis连接池配置
        jpBuilder.poolConfig(jedisPoolConfig);
        // 设置连接超时
        // 根据不同版本使用不同的超时设置方法
        JedisClientConfiguration jedisClientConfiguration = jpBuilder.build();

        // 创建Jedis连接工厂
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(redisStandaloneConfiguration,
                jedisClientConfiguration);

        // 如果配置文件存在，设置Redis启动参数，使其应用持久化配置
        configureRedisPersistence();

        return jedisConnectionFactory;
    }

    /**
     * 配置RedisTemplate
     * 设置添加序列化器，作为异常处理机制
     * 使用该模板操作redis，可以处理对象的存储
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        // 设置序列化
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());

        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    /**
     * 配置Redis持久化
     * 检查配置文件是否存在并设置启动参数
     */
    private void configureRedisPersistence() {
        if (redisConfigFilePath != null) {
            File configFile = new File(redisConfigFilePath);
            if (configFile.exists()) {
                // 设置JVM系统属性，这些属性会被Redis客户端库使用
                System.setProperty("redis.config.file", configFile.getAbsolutePath());

                // 输出持久化配置状态
                System.out.println("Redis持久化配置已启用: RDB=" + rdbEnabled + ", AOF=" + aofEnabled);
                System.out.println("Redis配置文件路径: " + configFile.getAbsolutePath());

                // 注意：这里的系统属性设置只是模拟，实际上Jedis可能不会使用这个属性
                // 在实际项目中，可能需要使用Redis官方客户端或其他方式启动Redis服务器并应用配置
            } else {
                System.out.println("Redis配置文件不存在: " + configFile.getAbsolutePath());
            }
        }
    }
}
